﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using KSS.Generator.Configuration;

namespace KSS.Generator
{
    class StructureGenerator
    {
        private GeneratorContext _context;
        public GeneratorContext Context
        {
            get
            {
                if (_context == null)
                {
                    _context = new GeneratorContext();
                }

                return _context;
            }
            set { _context = value; }
        }

        /// <summary>
        /// Generate projects folder and normal file depend on configuration and template files in Setting field
        /// </summary>
        public void Generate()
        {
            // retrieve all project configuration
            DirectoryInfo templateDirectory = null;
            DirectoryInfo generatedDirectory = null;

            foreach (ProjectSetting projectConfig in Context.Setting.Projects)
            {
                // find the appropriate template directory
                templateDirectory = Context.GetTemplateDirectory(projectConfig.TemplateFolderName);

                if (templateDirectory == null)
                {
                    continue;
                }

                // Create generated project folder
                generatedDirectory = Directory.CreateDirectory(Context.Setting.GeneratedFolderPath + projectConfig.ProjectFolderName);

                // Add generated directory to context
                Context.GeneratedDirectories.Add(generatedDirectory);

                // Generate directories and files
                GenerateDirectory(projectConfig, templateDirectory, generatedDirectory);
            }
        }

        private void GenerateDirectory(ProjectSetting projectConfig,
                                    DirectoryInfo templateDirectory,
                                    DirectoryInfo generatedDirectory)
        {
            #region { Generate files }

            string generatedFilePath = string.Empty;
            string template = string.Empty;

            // retrieve all template files
            FileInfo[] templateFiles = templateDirectory.GetFiles("*" + Template.TEMPLATE_FILE_EXTENSION);

            foreach (FileInfo fiTemplateFile in templateFiles)
            {
                // By pass the special template file (file bound with [])
                if (GeneratorHelper.CheckIfSpecialFile(fiTemplateFile.Name))
                {
                    continue;
                }

                // read the template file
                template = GeneratorHelper.ReadFromFile(fiTemplateFile.FullName);

                // fill in template value by retrieve all property setting
                template = GeneratorHelper.FillProperties(projectConfig,
                                                        template,
                                                        PropertyType.Local,
                                                        PropertyType.Global);

                // create generated file                
                generatedFilePath = generatedDirectory.FullName + "\\" + GeneratorHelper.GetFileNameFromat(fiTemplateFile.Name);

                if (GeneratorHelper.CheckIfOverridableFile(projectConfig.Name, fiTemplateFile.Name))
                {
                    // write to source file
                    GeneratorHelper.WriteToFile(generatedFilePath, template);
                }
                else
                {
                    // write to source file
                    GeneratorHelper.WriteToFile(generatedFilePath, template, true);
                }
            }
            #endregion

            #region { Generate child folders }

            DirectoryInfo[] childTemplateDirectories = templateDirectory.GetDirectories();
            DirectoryInfo childGeneratedDirectory = null;

            foreach (DirectoryInfo childDirectory in childTemplateDirectories)
            {
                childGeneratedDirectory = generatedDirectory.CreateSubdirectory(childDirectory.Name);
                GenerateDirectory(projectConfig, childDirectory, childGeneratedDirectory);
            }
            #endregion
        }
    }
}